import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.WindowConstants;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;
import javax.swing.JPanel;
import java.awt.Color;
import java.math.BigDecimal;

import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JSlider;
import javax.swing.border.BevelBorder;
import javax.swing.JSeparator;

/*
 * This window is used show the progress bar representing the power usage of servers.
 * It will only show up-to a certain number of servers at one time, and if there are any servers not shown, it will move onto the next
 * set of servers (Window time of around 10-20 seconds for each set of servers). 
 * 
 * == NOTE : This window will only open if there is at-least one server in the system. 
 */

public class SystemUsageWindow {

	protected volatile IServerCluster serverCluster = null;
	
	private JFrame frmSystemUsage;
	private JTextField text_serverID1;
	private JTextField text_serverID2;
	private JTextField text_serverID3;
	private JTextField text_serverID4;
	private JTextField text_serverID5;
	private JTextField text_serverID6;
	private JTextField text_serverID7;
	private JTextField text_viewChangeSecs;
	private JProgressBar progressBar1;
	private JProgressBar progressBar2;
	private JProgressBar progressBar3;
	private JProgressBar progressBar4;
	private JProgressBar progressBar5;
	private JProgressBar progressBar6;
	private JProgressBar progressBar7;
	private JLabel lblTotalNoOf;
	private JTextField text_totalServerCount;
	private JSlider slider_changeValue;
	private JLabel lblChooseViewingTime;

	/**
	 * Launch the application.
	 */
	public void startWindow() {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					frmSystemUsage.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public SystemUsageWindow(IServerCluster serverCluster) 
	{
		this.serverCluster = serverCluster;
		
		initialize();
		startSystemUsageThread();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmSystemUsage = new JFrame();
		frmSystemUsage.setTitle("System Usage");
		frmSystemUsage.setBounds(100, 100, 584, 500);
		frmSystemUsage.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		frmSystemUsage.getContentPane().setLayout(null);
		
		JPanel panel = new JPanel();
		panel.setBackground(new Color(112, 128, 144));
		panel.setBounds(6, 6, 572, 466);
		frmSystemUsage.getContentPane().add(panel);
		panel.setLayout(null);
		
		progressBar1 = new JProgressBar();
		progressBar1.setStringPainted(true);
		progressBar1.setOrientation(SwingConstants.VERTICAL);
		progressBar1.setBounds(22, 104, 26, 257);
		panel.add(progressBar1);
		
		text_serverID1 = new JTextField();
		text_serverID1.setForeground(new Color(255, 255, 255));
		text_serverID1.setHorizontalAlignment(SwingConstants.CENTER);
		text_serverID1.setText("0");
		text_serverID1.setBackground(new Color(147, 112, 219));
		text_serverID1.setEditable(false);
		text_serverID1.setBounds(6, 36, 56, 28);
		panel.add(text_serverID1);
		text_serverID1.setColumns(10);
		
		JLabel lblServerIds = new JLabel("Server ID's");
		lblServerIds.setBounds(249, 6, 71, 16);
		panel.add(lblServerIds);
		
		text_serverID2 = new JTextField();
		text_serverID2.setForeground(new Color(255, 255, 255));
		text_serverID2.setText("1");
		text_serverID2.setHorizontalAlignment(SwingConstants.CENTER);
		text_serverID2.setEditable(false);
		text_serverID2.setColumns(10);
		text_serverID2.setBackground(new Color(147, 112, 219));
		text_serverID2.setBounds(87, 36, 56, 28);
		panel.add(text_serverID2);
		
		text_serverID3 = new JTextField();
		text_serverID3.setText("2");
		text_serverID3.setForeground(new Color(255, 255, 255));
		text_serverID3.setHorizontalAlignment(SwingConstants.CENTER);
		text_serverID3.setEditable(false);
		text_serverID3.setColumns(10);
		text_serverID3.setBackground(new Color(147, 112, 219));
		text_serverID3.setBounds(170, 36, 56, 28);
		panel.add(text_serverID3);
		
		text_serverID4 = new JTextField();
		text_serverID4.setForeground(new Color(255, 255, 255));
		text_serverID4.setHorizontalAlignment(SwingConstants.CENTER);
		text_serverID4.setText("3");
		text_serverID4.setEditable(false);
		text_serverID4.setColumns(10);
		text_serverID4.setBackground(new Color(147, 112, 219));
		text_serverID4.setBounds(249, 36, 56, 28);
		panel.add(text_serverID4);
		
		text_serverID5 = new JTextField();
		text_serverID5.setForeground(new Color(255, 255, 255));
		text_serverID5.setText("4");
		text_serverID5.setHorizontalAlignment(SwingConstants.CENTER);
		text_serverID5.setEditable(false);
		text_serverID5.setColumns(10);
		text_serverID5.setBackground(new Color(147, 112, 219));
		text_serverID5.setBounds(330, 36, 56, 28);
		panel.add(text_serverID5);
		
		text_serverID6 = new JTextField();
		text_serverID6.setForeground(new Color(255, 255, 255));
		text_serverID6.setHorizontalAlignment(SwingConstants.CENTER);
		text_serverID6.setText("5");
		text_serverID6.setEditable(false);
		text_serverID6.setColumns(10);
		text_serverID6.setBackground(new Color(147, 112, 219));
		text_serverID6.setBounds(409, 36, 56, 28);
		panel.add(text_serverID6);
		
		text_serverID7 = new JTextField();
		text_serverID7.setText("6");
		text_serverID7.setForeground(new Color(255, 255, 255));
		text_serverID7.setHorizontalAlignment(SwingConstants.CENTER);
		text_serverID7.setEditable(false);
		text_serverID7.setColumns(10);
		text_serverID7.setBackground(new Color(147, 112, 219));
		text_serverID7.setBounds(488, 36, 56, 28);
		panel.add(text_serverID7);
		
		progressBar2 = new JProgressBar();
		progressBar2.setStringPainted(true);
		progressBar2.setOrientation(SwingConstants.VERTICAL);
		progressBar2.setBounds(103, 104, 26, 257);
		panel.add(progressBar2);
		
		progressBar3 = new JProgressBar();
		progressBar3.setStringPainted(true);
		progressBar3.setOrientation(SwingConstants.VERTICAL);
		progressBar3.setBounds(188, 104, 26, 257);
		panel.add(progressBar3);
		
		progressBar4 = new JProgressBar();
		progressBar4.setStringPainted(true);
		progressBar4.setOrientation(SwingConstants.VERTICAL);
		progressBar4.setBounds(266, 104, 26, 257);
		panel.add(progressBar4);
		
		progressBar5 = new JProgressBar();
		progressBar5.setStringPainted(true);
		progressBar5.setOrientation(SwingConstants.VERTICAL);
		progressBar5.setBounds(349, 104, 26, 257);
		panel.add(progressBar5);
		
		progressBar6 = new JProgressBar();
		progressBar6.setStringPainted(true);
		progressBar6.setOrientation(SwingConstants.VERTICAL);
		progressBar6.setBounds(425, 104, 26, 257);
		panel.add(progressBar6);
		
		progressBar7 = new JProgressBar();
		progressBar7.setStringPainted(true);
		progressBar7.setOrientation(SwingConstants.VERTICAL);
		progressBar7.setBounds(508, 104, 26, 257);
		panel.add(progressBar7);
		
		JLabel lblNextChangeIn = new JLabel("Time till next change (Secs):");
		lblNextChangeIn.setBounds(299, 444, 184, 16);
		panel.add(lblNextChangeIn);
		
		text_viewChangeSecs = new JTextField();
		text_viewChangeSecs.setText("0");
		text_viewChangeSecs.setHorizontalAlignment(SwingConstants.CENTER);
		text_viewChangeSecs.setForeground(Color.WHITE);
		text_viewChangeSecs.setEditable(false);
		text_viewChangeSecs.setColumns(10);
		text_viewChangeSecs.setBackground(new Color(147, 112, 219));
		text_viewChangeSecs.setBounds(495, 438, 71, 28);
		panel.add(text_viewChangeSecs);
		
		lblTotalNoOf = new JLabel("Total No. of Servers:");
		lblTotalNoOf.setBounds(6, 444, 137, 16);
		panel.add(lblTotalNoOf);
		
		text_totalServerCount = new JTextField();
		text_totalServerCount.setText("0");
		text_totalServerCount.setHorizontalAlignment(SwingConstants.CENTER);
		text_totalServerCount.setForeground(Color.WHITE);
		text_totalServerCount.setEditable(false);
		text_totalServerCount.setColumns(10);
		text_totalServerCount.setBackground(new Color(147, 112, 219));
		text_totalServerCount.setBounds(143, 438, 71, 28);
		panel.add(text_totalServerCount);
		
		slider_changeValue = new JSlider();
		slider_changeValue.setBorder(new BevelBorder(BevelBorder.RAISED, Color.BLACK, null, null, null));
		slider_changeValue.setPaintTicks(true);
		slider_changeValue.setMinorTickSpacing(5);
		slider_changeValue.setToolTipText("Choose the amount of seconds to view each set of servers");
		slider_changeValue.setPaintLabels(true);
		slider_changeValue.setBackground(Color.WHITE);
		slider_changeValue.setMajorTickSpacing(5);
		slider_changeValue.setValue(10);
		slider_changeValue.setMaximum(30);
		slider_changeValue.setMinimum(5);
		slider_changeValue.setBounds(280, 383, 244, 44);
		panel.add(slider_changeValue);
		
		lblChooseViewingTime = new JLabel("Choose viewing time (Secs):");
		lblChooseViewingTime.setBounds(60, 397, 184, 16);
		panel.add(lblChooseViewingTime);
		
		JSeparator separator = new JSeparator();
		separator.setForeground(new Color(255, 255, 255));
		separator.setBounds(6, 12, 238, 12);
		panel.add(separator);
		
		JSeparator separator_1 = new JSeparator();
		separator_1.setForeground(new Color(255, 255, 255));
		separator_1.setBounds(319, 10, 247, 12);
		panel.add(separator_1);
		
		JLabel lblServerPowerConsumption = new JLabel("Server Power Consumption Bars");
		lblServerPowerConsumption.setBounds(190, 76, 206, 16);
		panel.add(lblServerPowerConsumption);
		
		JSeparator separator_2 = new JSeparator();
		separator_2.setForeground(Color.WHITE);
		separator_2.setBounds(6, 80, 172, 12);
		panel.add(separator_2);
		
		JSeparator separator_3 = new JSeparator();
		separator_3.setForeground(Color.WHITE);
		separator_3.setBounds(394, 80, 172, 12);
		panel.add(separator_3);
	}

	public JTextField getText_serverID1() {
		return text_serverID1;
	}
	public JTextField getText_serverID2() {
		return text_serverID2;
	}
	public JTextField getText_serverID3() {
		return text_serverID3;
	}
	public JTextField getText_serverID4() {
		return text_serverID4;
	}
	public JTextField getText_serverID5() {
		return text_serverID5;
	}
	public JTextField getText_serverID6() {
		return text_serverID6;
	}
	public JTextField getText_serverID7() {
		return text_serverID7;
	}
	public JTextField getText_viewChangeSecs() {
		return text_viewChangeSecs;
	}
	
	private void startSystemUsageThread()
	{
		Runnable systemUsageUpdate = new Runnable()
		{
			public void run()
			{
				int currentlyStoredSliderValue = slider_changeValue.getValue();
				int changeCounter = currentlyStoredSliderValue;
				int count = 0;
				double ratio = 0;
				int remainder = 0;
				
				while(true)
				{
					// Keep updating the system usage data
				
					int serverCount = serverCluster.getServerCount();
					
					if(serverCount <=7)
						slider_changeValue.setEnabled(false);
					else
						slider_changeValue.setEnabled(true);
					
					text_totalServerCount.setText(null);
					text_totalServerCount.setText(String.valueOf(serverCount));
					
					if(serverCount <= 7)
					{
						// Do normally without any changes
						
						resetAllParameters();
						
						for(int i=0;i<serverCount;i++)
						{
							// Update the server ID's
							
							getServerIDField(i+1).setText(null);
							getServerIDField(i+1).setText(String.valueOf(serverCluster.getServer(i).getServerID()));
							
							// Update the progress bar maximum value
							
							getProgressBar(i+1).setMaximum((int) serverCluster.getServer(i).getMaxPower());
							
							// Update the progress bar current value
							
							getProgressBar(i+1).setIndeterminate(false);
							getProgressBar(i+1).setStringPainted(true);
							getProgressBar(i+1).setValue((int) serverCluster.getServer(i).getPowerConsumption());
						}
					}
					
					else
					{
						ratio = calculateAccurateDouble((double) serverCount/7.0);
						remainder = serverCount % 7;
						
						if(changeCounter == currentlyStoredSliderValue)		// Change over after 20 Seconds
						{
							resetAllParameters();
							
							changeCounter = 0;
							currentlyStoredSliderValue = slider_changeValue.getValue();
							
							if(count < (int) ratio)
							{
								// Show all servers until last multiple of 7
								
								for(int i=0;i<7;i++)
								{
									//getServerIDField(i).setText(null);
									getServerIDField(i+1).setText(String.valueOf(serverCluster.getServer(i + (count*7)).getServerID()));
									
									// Update the progress bar maximum value
									
									getProgressBar(i+1).setMaximum((int) serverCluster.getServer(i + (count*7)).getMaxPower());
									
									// Update the progress bar current value
									
									getProgressBar(i+1).setIndeterminate(false);
									getProgressBar(i+1).setStringPainted(true);
									getProgressBar(i+1).setValue((int) serverCluster.getServer(i + (count*7)).getPowerConsumption());
								}
								
								count++;
							}
							
							else
							{
								// Show rest of remaining servers i.e after the last multiple of 7
								
								if(remainder > 0)
								{
									for(int i=0;i<remainder;i++)
									{
										//getServerIDField(i).setText(null);
										getServerIDField(i+1).setText(String.valueOf(serverCluster.getServer(i + (count*7)).getServerID()));
										
										// Update the progress bar maximum value
										
										getProgressBar(i+1).setMaximum((int) serverCluster.getServer(i + (count*7)).getMaxPower());
										
										// Update the progress bar current value
										
										getProgressBar(i+1).setIndeterminate(false);
										getProgressBar(i+1).setStringPainted(true);
										getProgressBar(i+1).setValue((int) serverCluster.getServer(i + (count*7)).getPowerConsumption());
									}
									
									count = 0;
								}
							}
						}
											
						text_viewChangeSecs.setText(String.valueOf(currentlyStoredSliderValue-changeCounter));
						
						changeCounter++;
					}
					
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		
		Thread systemUsageUpdateThread = new Thread(systemUsageUpdate);
		systemUsageUpdateThread.start();
	}
	
	private void resetAllParameters()
	{
		// Reset the Server ID Field & Progress Bar
		
		for(int i=1;i<=7;i++)
		{
			getServerIDField(i).setText("N/A"); 
			getProgressBar(i).setIndeterminate(true);
			getProgressBar(i).setValue(0);
		}
		
		text_viewChangeSecs.setText("N/A");
	}
	
	private JTextField getServerIDField(int i)
	{
		switch(i)
		{
		case 1 : return text_serverID1;
		case 2 : return text_serverID2;
		case 3 : return text_serverID3;
		case 4 : return text_serverID4;
		case 5 : return text_serverID5;
		case 6 : return text_serverID6;
		case 7  :return text_serverID7;
		default : return null;
		}
	}
	
	private JProgressBar getProgressBar(int i)
	{
		switch(i)
		{
		case 1 : return progressBar1;
		case 2 : return progressBar2;
		case 3 : return progressBar3;
		case 4 : return progressBar4;
		case 5 : return progressBar5;
		case 6 : return progressBar6;
		case 7 : return progressBar7;
		default : return null;
		}
	}
	
	public JProgressBar getProgressBar1() {
		return progressBar1;
	}
	public JProgressBar getProgressBar2() {
		return progressBar2;
	}
	public JProgressBar getProgressBar3() {
		return progressBar3;
	}
	public JProgressBar getProgressBar4() {
		return progressBar4;
	}
	public JProgressBar getProgressBar6() {
		return progressBar6;
	}
	public JProgressBar getProgressBar7() {
		return progressBar7;
	}
	public JProgressBar getProgressBar5() {
		return progressBar5;
	}
	
	private double calculateAccurateDouble(double value)
	{
		BigDecimal decimal = new BigDecimal(value);
		decimal = decimal.setScale(2, BigDecimal.ROUND_HALF_UP);
		
		return decimal.doubleValue();
	}
	public JTextField getText_totalServerCount() {
		return text_totalServerCount;
	}
	public JSlider getSlider_changeValue() {
		return slider_changeValue;
	}
}
